﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ThiefRun.Character;
using Microsoft.Xna.Framework;

namespace ThiefRun.Behaviour
{
    public static class KinematicBehaviour
    {
        public static void Wander(ref MovementProperties linear, ref MovementProperties angular, ref MovementProperties targetLinear, ref MovementProperties targetAngular, AIProperties aiProperties)
        {
            /*int sign = (Game1.random.Next(0, 1) == 0) ? -1 : 1;
            
            angular.velocity = sign * aiProperties.maxAngular.velocity;
            angular.position += angular.velocity;*/
            
            //KinematicBehaviour.Seek(ref linear, ref targetLinear);
            KinematicBehaviour.Align(linear, ref angular);
        }

        public static void Seek(ref MovementProperties linear, ref MovementProperties targetLinear)
        {

        }

        // Align with the direction of motion.
        public static void Align(MovementProperties linear, ref MovementProperties angular)
        {
            Vector2 temp = linear.velocity;
            temp.Normalize();

            //angular.position.Y = (float)Math.Asin(temp.X);
            //angular.position.Y = (float)Math.Acos(temp.Z);
        }
        
        /*private void KinematicArrive()
        {
            float len = linear.velocity.Length();
            // The character is stationary or moving very slowly (A)
            if ((linear.velocity == Vector3.Zero) || (linear.velocity.Length() <= SLOW_VELOCITY))
            {
                // small distance from target (Ai)
                if (nearSphere.Intersects(target.boundingSphere))
                {
                    // step there directly, even if this involves moving backward or sidestepping
                    // Velocity must not exceed the maxium velocity.
                    linear.velocity.X = Math.Min(MaxVelocity(), (target.linear.position.X - linear.position.X) / TIME_TO_TARGET);
                    linear.velocity.Z = Math.Min(MaxVelocity(), (target.linear.position.Z - linear.position.Z) / TIME_TO_TARGET);
                    linear.position += linear.velocity;
                }
                // far from target (Aii)
                else
                {
                    // turn on the spot towards target
                    Face();
                    //direction.Y += ((target.direction.Y + MathHelper.ToRadians(180)) - direction.Y) / TIME_TO_ALIGN;

                    // move towards target
                    KinematicSeek();
                    /*velocity.X = MAXIMUM_VELOCITY;
                    velocity.Z = MAXIMUM_VELOCITY;

                    position += velocity;
                    //position += currentVelocity;
                }
            }
            else
            {
                // if in speed dependent arc (cone of perception) and in front (Bi).
                if (false)
                {
                    // move forward with rotation.
                }
                // Target outside cone of perception (Bii)
                else
                {
                    // stop
                    linear.velocity = Vector3.Zero;

                    // change direction
                    // turn on the spot towards target
                    Face();
                    //direction.Y += ((target.direction.Y + MathHelper.ToRadians(180)) - direction.Y) / TIME_TO_ALIGN;

                    // move towards target
                    KinematicSeek();
                    /*velocity.X = (float)(MAXIMUM_VELOCITY * Math.Sin(direction.Y));
                    velocity.Z = (float)(MAXIMUM_VELOCITY * Math.Cos(direction.Y));
                    //position += currentVelocity;
                    position += velocity;
                }
            }
        }*/

        /*private void KinematicEvade()
        {
            // small distance from target (Ci)
            if (nearSphere.Intersects(target.boundingSphere))
            {
                // step there directly, even if this involves moving backward or sidestepping
                // Velocity must not exceed the maxium velocity.
                linear.velocity.X = Math.Min(MaxVelocity(), (linear.position.X - target.linear.position.X) / TIME_TO_TARGET);
                linear.velocity.Z = Math.Min(MaxVelocity(), (linear.position.Z - target.linear.position.Z) / TIME_TO_TARGET);
                linear.position += linear.velocity;
            }
            // far from target (Cii)
            else
            {
                // turn on the spot towards target
                FaceAway();
                //direction.Y += (target.direction.Y - direction.Y) / TIME_TO_ALIGN;

                // move towards target
                KinematicSeek();
                /*velocity.X = MAXIMUM_VELOCITY * d;
                velocity.Z = MAXIMUM_VELOCITY;
                position += velocity;
                //position += currentVelocity;
            }
        }*/
        /*private void Face()
        {
            angular.position.Y += MathHelper.ToRadians(180) / TIME_TO_ALIGN;
        }

        private void FaceAway()
        {
            angular.position.Y = target.angular.position.Y;
        }*/

        /*private void KinematicSeek()
        {
            linear.velocity.X = (float)(MaxVelocity() * Math.Sin(angular.position.Y));
            linear.velocity.Z = (float)(MaxVelocity() * Math.Cos(angular.position.Y));
            linear.position += linear.velocity;
        }*/
    }
}
